The Object Browser |
It is a tool that can be open from Microsoft Visual Studio View > Object Browser to browse COM objects see the figures below. The browser displays:
Es una herramienta que puede abrirse desde Microsoft Visual Studio View > Object Browser para explorar los objetos COM vea las figuras de abajo. El explorador muestra.
|
Problem 1 |
Browse Application.Word using the Object Browser.
Explore Application.Word usando el Explorar de Objetos.
|
Visual Basic and Macros |
Microsoft Word, Microsoft Excel, Corel Draw and other programs have the option to use Macros. Macros are programs written in Microsoft Visual Basic that allows performing complex tasks using code. Microsoft Visual Basic can be used to know the name of the functions executed when the user manipulates the program with the mouse and the keyboard. Microsoft Word, Microsoft Excel, Corel Draw y otros programas tienen la opción de usar Macros. Los Macros son programas escritos en Microsoft Visual Basic que permiten realizar tareas complejas usando código. Microsoft Visual Basic puede ser usado para conocer el nombre de las funciones ejecutadas cuando el usuario manipula el programa con el ratón y el teclado. |
Problem 2 |
Generate a Macro in Microsoft Word to open a file.
|
Tip |
En Corel Draw you will find Microsoft Visual Basic in the Tools menu. En Corel Draw usted encontrará Microsoft Visual Basic en el menú de Herramientas. |
Get, Put, PutRef. |
There are four basic operations that can be used in COM: Get, Put, PutRef and Method. They are illustrated below. Get is used to extract information from an object; usually it does not take any parameters. Put is used to set the value of a property, it takes usually one single parameter. PutRef is used to pass a value by reference. Hay cuatro operaciones básicas que pueden usarse en COM: Get, Put, PutRef y Method. Estas son ilustradas abajo. Get es usado para extraer información de un objeto; usualmente este no toma ningún parámetro. Put es usado para fijar el valor de una propiedad, este toma usualmente un solo parámetro. PutRef es usado para pasar un valor por referencia. |
Method |
Method is used to execute a method (call a function); it may take several parameters and returns one value. There are several ways to call a method. However, you must remember that in most cases the last parameter of a method is the returned value from the method. Thus, if a method takes two parameters, the function will take four parameters: the name of the method, parameter 1, parameter 2, and the returned value as shown in the second figure below. Method es usado para ejecutar un método (llamar una función); este puede tomar varios parámetros y regresar un valor. Hay varias formas de llamar un método. Sin embargo, usted debe recordar que en la mayoría de los casos el último parámetro de un método es el valor regresado por el método. Así, si un método toma dos parámetros, la función tomará cuatro parámetros: el nombre del método, el parámetro 1, el parámetro 2, y el valor que regresa el método como se ilustra en la segunda figura de abajo. |
Com::Object vs. _variant_t |
In some cases it is necessary to pass a Com::Object to a method, however, the method takes only _variant_t variables. In these cases it is necessary to convert the Com::Object to a _variant_t variable as shown below. En algunos casos es necesario pasar un Com::Object a un método, sin embargo, el método sólo toma variables del tipo_variant_t. En estos casos es necesario convertir el Com::Object a una variable del tipo _variant_t como se muestra. |
Progam.cpp |
void Programm::Window_Open(Win::Event& e) { ... Com::Object Document; Com::Object options; _variant_t result; try { ... _variant_t vtOptions(options.dispatch.GetInterfacePtr()); // From: Com::Object to _variant_t Document.Method(L"Process", vtOptions, result); } catch(Com::Exception excep) { ... } } |
Optional Parameter |
Some Methods (functions) have optional parameter. The required parameters are always first than the optional parameters. It is possible to call a Method using only the required parameters. It is also possible to pass the required parameters and part of the optional parameters. Additionally, it is also possible to pass values to all required parameters, and empty values to all (or some) of the optional parameters. Algunos métodos (funciones) tienen parámetros opcionales. Los parámetros requeridos siempre están primero que los parámetros opcionales. Es posible llamar un método usando solamente los parámetros requeridos. También es posible pasar los parámetros requeridos y parte de los parámetros opcionales. Adicionalmente, es posible pasar valores a todos los parámetros requeridos, y valores vacíos a todos (o a algunos) de los parámetros opcionales. |
Problem 3 |
This example shows how to use COM without Smart Pointers and without Wintempla. You must create a console Win32 application called MsOpen32. The program will open Microsoft Word for five seconds, and then the program will call Quit to close Microsoft Word. As the program uses Structured Programming, it is very complex and it is very make mistakes. You should never write code as the one shown. Este ejemplo muestra cómo usar COM sin los Punteros Inteligentes y sin Wintempla. Usted debe crear una aplicación de consola Win32 llamada MsOpen32. El programa abrirá Microsoft Word por cinco segundos, y entonces el programa llamará Quit para cerrar Microsoft Word. Como el programa usa la Programación Estructura, este es muy complejo y es muy fácil cometer errores. Nunca escriba código como el mostrado. |
MsOpen32.cpp |
// MsOpen32.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "windows.h" #include <iostream> // For cout int _tmain(int argc, _TCHAR* argv[]) { ::CoInitialize(NULL); HRESULT hr; //____________________________________________________________________ Get Word.Application CLSID CLSID clsid; hr = ::CLSIDFromProgID(L"Word.Application", &clsid); if (FAILED(hr)) { std::cout<<"Unable to find Word.Application CLSID"; ::CoUninitialize(); return 0; } //____________________________________________________________________ 1. Create Word.Application and Get IUnknown IUnknown* unknown = NULL; hr = ::CoCreateInstance(clsid, NULL, CLSCTX_ALL, __uuidof(IUnknown), reinterpret_cast<void**>(&unknown)); //hr = dispatch.CreateInstance(clsid, NULL, CLSCTX_ALL); if (FAILED(hr)) { std::cout<<"Error: 1. Create Word.Application and Get IUnknown"; ::CoUninitialize(); return 0; } //____________________________________________________________________ 2. Object Linking and Embeding hr = OleRun(unknown); if (FAILED(hr)) { std::cout<<"Error: 2. Object Linking and Embeding"; unknown->Release(); ::CoUninitialize(); return 0; } //____________________________________________________________________ 3. Get IDispatch IDispatch* dispatch = NULL; hr = unknown->QueryInterface(IID_IDispatch, reinterpret_cast<void**>(&dispatch)); unknown->Release(); // we do not need IUnknown any longer if (FAILED(hr)) { std::cout<<"Error: 3. Get IDispatch"; ::CoUninitialize(); return 0; } //_____________________________________________________________________4. Get DISPID of Visible DISPID dispidVisible; LPOLESTR visibleName = L"Visible"; hr = dispatch->GetIDsOfNames(IID_NULL, &visibleName, 1, LOCALE_SYSTEM_DEFAULT, &dispidVisible) ; if (FAILED(hr)) { std::cout<<"Error: 4. Get DISPID of Visible"; dispatch->Release(); ::CoUninitialize(); return 0; } //_____________________________________________________________________5. Prepare parameter for Visible VARIANT param[1]; ::VariantInit(param[0]); param[0].vt = VT_BOOL; param[0].boolVal = VARIANT_TRUE; //______________________________ Parameters DISPPARAMS dispParam; DISPID dispidParam[1]; dispParam.rgvarg = param; dispParam.cArgs = 1; dispParam.cNamedArgs = 1; dispidParam[0] = DISPID_PROPERTYPUT; dispParam.rgdispidNamedArgs = dispidParam; //_____________________________ Returned value VARIANT returnedValue; ::VariantInit(&returnedValue); //_____________________________________________________________________6. Call Visible using IDispatch::Invoke EXCEPINFO excepInfo; UINT argError; hr = dispatch->Invoke(dispidVisible, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &dispParam, &returnedValue, &excepInfo, &argError); if (FAILED(hr)) { std::cout<<"Error: 6. Call Visible using IDispatch::Invoke"; dispatch->Release(); ::CoUninitialize(); return 0; } //_____________________________________________________________________7. Put Thread to Sleep so that we can see Microsoft Word ::Sleep(5000); //_____________________________________________________________________8. Get DISPID of Quit DISPID dispidQuit; LPOLESTR quitName = L"Quit"; hr = dispatch->GetIDsOfNames(IID_NULL, &quitName, 1, LOCALE_SYSTEM_DEFAULT, &dispidQuit) ; if (FAILED(hr)) { std::cout<<"Error: 8. Get DISPID of Quit"; dispatch->Release(); ::CoUninitialize(); return 0; } //_____________________________________________________________________9. Prepare parameters for Quit dispParam.rgvarg = NULL; dispParam.cArgs = 0; dispParam.cNamedArgs = 0; dispParam.rgdispidNamedArgs = NULL; //_____________________________________________________________________10. Call Quit using IDispatch::Invoke hr = dispatch->Invoke(dispidQuit, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispParam, &returnedValue, &excepInfo, &argError); if (FAILED(hr)) { std::cout<<"Error: 10. Call Quit using IDispatch::Invoke"; dispatch->Release(); ::CoUninitialize(); return 0; } dispatch->Release(); ::CoUninitialize(); return 0; } |
Problem 4 |
Create a Wintempla Dialog Application called MsOpen to open a file from your hard drive. Cree una aplicación de Diálogo llamada MsOpen para abrir un archivo desde su disco duro. |
MsOpen.h |
#pragma once //______________________________________ MsOpen.h #include "resource.h" class MsOpen: public Win::Dialog { public: MsOpen() { ::CoInitialize(NULL); } ~MsOpen() { ::CoUninitialize(); } ... }; |
MsOpen.cpp |
... void MsOpen::Window_Open(Win::Event& e) { Com::Object Application; Com::Object Documents; Com::Object Document; try { Application.CreateInstance(L"Word.Application", true); Application.Put(L"Visible", true); Application.Get(L"Documents", Documents); Documents.Method(L"Open", L"C:\\selo\\110\\borrar.docx", //FileName: false, //ConfirmConversions false, // ReadOnly false, //AddToRecentFiles L"", //PasswordDocument L"", // PasswordTemplate false, // Revert L"", //WritePasswordDocument L"", // WritePasswordTemplate (short)0, // Format: Word::WdOpenFormat::wdOpenFormatAuto (short)50001, // Encoding: Office::MsoEncoding::msoEncodingAutoDetect true, // Visible false, // OpenAndRepair, (short)0, // DocumentDirection: Word::WdDocumentDirection::wdLeftToRight true, //NoEncodingDialog L"", //XMLTransform Document); // The returned object is the open Document } catch(Com::Exception excep) { excep.Display(hWnd, L"MsOpen"); Application.Method(L"Quit"); } } |
Tip |
You may use the Object Explorer to know the value of each of enum values. For instance, the Encoding Auto Detect has a value of 50001, and is declared in Office::Mso in the mso.dll file. We will explain later how to extract this information from a DLL. See figure below. Usted puede usar el Explorador de Objetos para conocer el valor de cada una de las enumeraciones. Por ejemplo, el Encoding Auto Detect tiene un valor de 50001, y está declarado en Office::Mso en el archivo mso.dll. Nosotros explicaremos después como extraer esta información desde una DLL. Vea la figura de abajo. |
Problem 5 |
In some cases, it is better to declare an array of _variant_t to pass parameter to a method as illustrated in the following code. En algunos casos, es mejor declarar un arreglo de _variant_t para pasar parámetros a un método como se ilustra en el código de abajo. |
MsOpen.cpp |
... void MsOpen::Window_Open(Win::Event& e) { Com::Object Application; Com::Object Documents; Com::Object Document; Com::Param param; try { Application.CreateInstance(L"Word.Application", true); Application.Put(L"Visible", true); Application.Get(L"Documents", Documents); param.Create(16); param[0] = L"C:\\selo\\110\\borrar.docx"; //FileName: param[1] = false; //ConfirmConversions param[2] = false; // ReadOnly param[3] = false; //AddToRecentFiles param[4] = L""; //PasswordDocument param[5] = L""; // PasswordTemplate param[6] = false; // Revert param[7] = L""; //WritePasswordDocument param[8] = L""; // WritePasswordTemplate param[9] = (short)0;// Format: Word::WdOpenFormat::wdOpenFormatAuto param[10] = (short)50001; // Encoding: Office::MsoEncoding::msoEncodingAutoDetect param[11] = true; // Visible param[12] = false; // OpenAndRepair, param[13] = (short)0;// DocumentDirection ; Word::WdDocumentDirection::wdLeftToRight param[14] = true; //NoEncodingDialog param[15] = L""; //XMLTransform Documents.Method(L"Open", param, Document); } catch(Com::Exception excep) { excep.Display(hWnd, L"MsOpen"); Application.Method(L"Quit"); } } |
Word.Application |
The Word.Application object represents the program of Microsoft Word. The Word.Application may have several Microsoft Word Documents open. However, only the ActiveDocument is active. When a Word.Application command is executed, it is assumed that this command will be applied to the ActiveDocument. The object browser, shown below, displays the Word.Application class. El objeto de Word.Application representa el programa de Microsoft Word. La Word.Application puede tener varios documentos de Microsoft Word abiertos. Sin embargo, solamente el ActiveDocument está activo. Cuando un comando de la Word.Application se ejecuta, se asume que el comando se aplicará al ActiveDocument. El explorador de objetos, mostrado debajo, ilustra la clase Word.Application |
Selection |
The Word.Application has a Selection to perform document manipulation; it represents where the Caret (the vertical line that blinks) is located. For instance to select the whole document, a program must call the method WholeStory of the Selection. The Selection allows copying, pasting, deleting, etc. Some of the most useful functions of the Selection are: TypeText (to type some text), TypeParagraph (to insert a new paragraph). These functions are displays in the figures below. Thus, the Selection interface is used to simulate the actions performed by the user, such as: pressing a key in the keyboard, pasting, selecting all, etc. La Word.Application tiene una Selection para realizar la manipulación del documento; este representa donde está el Caret (la barra vertical que parpadea). Por ejemplo para seleccionar todo el documento, un programa debe llamar el método WholeStory de la Selection. La Selection permite copiar, pegar, borrar, etc. Algunas de las funciones más útiles de la Selection son: TypeText (para introducir texto), TypeParagraph (para introducir un párrafo nuevo). Estas funciones se ilustras en las figuras de abajo. Así, la interface Selection es usada para simular las acciones realizadas por el usuario, tales como: presionar una tecla en el teclado, pegar, seleccionar todo, etc. |
Problem 6 |
Create a program called MsFruit to create a new Microsoft Word document. The program must write the name of five fruits (each fruit in a row) and save the file as Fruits.docx. Use the Object Browser or call Com::Container::DisplayInterfaceFunctions(hWnd, MyObject) to know more about the functions of the object or the interface.
Cree un programa llamado MsFruit para crear un nuevo documento de Microsoft Word. El programa debe escribir el nombre de cinco frutas (una fruta en un renglón) y guardar el archivo como Fruits.docx. Use el Explorador de Objetos o llame Com::Container::DisplayInterfaceFunctions(hWnd, MyObject) para conocer más acerca de las funciones del objeto o la interface.
|
MsFruit.cpp |
void MsFruit::Window_Open(Win::Event& e) { Com::Object Application; Com::Object Selection; Com::Object Documents; Com::Object ActiveDocument; _variant_t vresult; try { Application.CreateInstance(L"Word.Application", true); Application.Get(L"Documents", Documents); Documents.Method(L"Add"); //_____________________________________________________ Selection Application.Get(L"Selection", Selection); Selection.Method(L"TypeText", L"1. Apple", vresult); Selection.Method(L"TypeParagraph"); ... //_____________________________________________________ Save And Quit Application.Get(L"ActiveDocument", ActiveDocument); ... } catch(Com::Exception excep) { ... } } |